#include "struttura_dati.h"
#include <gtk/gtk.h>
#include "manip_mano.h"
#include <iostream>
#include "turno_pc.h"
#include <cstring>


using namespace std;

extern GtkBuilder *builder;
extern partita_t partita;
extern gioca_t gioca;
extern turno_t turno;

// dichiarazione di funzioni chiamate da funzioni definite prima
void setta_immagine_tavolo();
void pulisci_tavolo();
static void congela_gioco();

/** Funzione che restituisce il valore intero dell'indice della mano, 
 * corrispondente alla carta premuta. Ritorna un numero compreso tra 0 e 2.
 * Per la mano del player1, set_mano = true, per quella di player2 è false.
 */
int ricerca_id_carta(bool set_mano){
	D1(cout<<"INIZIO DEBUG ricerca_id_carta"<<endl);
	// Ricerca in player1.mano la carta con il campo selez a true
	int id=0;
	if(set_mano == true){
		for(int i=0; i<NUM_MANO; i++){
			if(partita.player1.mano[i].selez == true)
				id = i;
			}
		D2(cout<<"ho fatto la ricerca nella mano del giocatore"<<endl);
		}
	// Ricerca in player2.mano la carta con il campo selez a true
	else{
		for(int i=0; i<NUM_MANO; i++){
			if(partita.player2.mano[i].selez == true)
				id = i;
			}
		D2(cout<<"ho fatto la ricerca nella mano del computer"<<endl);
		}
	return id;
	D1(cout<<"FINE DEBUG RICERCA ID CARTA"<<endl);		
}

/** Funzione che controlla qundo la partita è finita.
 *  Il controllo lo fa sul punteggio, ovvero quando il punteggio complessivo
 *  di entrambi i giocatori è 120, vuol dire che la partita è finita, e fa 
 *  comparire le 2 dialog, nel modo giusto.
 *  Questa funzione quindi fa anche un controllo implicito sul punteggio.
 */
void gestore_fine_partita(){
	D1(cout<<"INIZIO DEBUG gestore_fine_partita"<<endl);
	
	if (partita.id_fine == 20){
		
		if(partita.player1.punteggio>=61)
			gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,
						"dialog3")),true);
		else if(partita.player1.punteggio==60)
			gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,
						"dialog5")),true);
		else
			gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,
						"dialog4")),true);
		D2(cout<<"controllo sui punti totalizzati"<<endl);
		pulisci_tavolo();
		D2(cout<<"pulito tavolo effettuato con successo"<<endl);
		congela_gioco();
		D2(cout<<"congelato gioco con successo"<<endl);
		gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(builder,
						"mazzo")),false);

		gtk_image_set_from_file(GTK_IMAGE(gtk_builder_get_object(builder, "0")),
						"./torre.gif");
		gtk_image_set_from_file(GTK_IMAGE(gtk_builder_get_object(builder, "1")), 
						"./torre.gif");
		gtk_image_set_from_file(GTK_IMAGE(gtk_builder_get_object(builder, "2")), 
						"./torre.gif");
		gtk_image_set_from_file(GTK_IMAGE(gtk_builder_get_object(builder, "3")), 
						"./torre.gif");
		gtk_image_set_from_file(GTK_IMAGE(gtk_builder_get_object(builder, "4")), 
						"./torre.gif");
		gtk_image_set_from_file(GTK_IMAGE(gtk_builder_get_object(builder, "5")), 
						"./torre.gif");

		gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,"0")),
						true);
		gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,"1")),
						true);
		gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,"2")),
						true);
		gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,"3")),
						true);
		gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,"4")),
						true);
		gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,"5")),
						true);
		}
	D1(cout<<"FINE DEBUG RICERCA ID CARTA"<<endl);
}

/** Funzione che gestisce i punteggi di entrambi i giocatori.
 *  Somma al punteggio precedente del giocatore vincente le due nuove carte.
 */
static void calcola_punteggio(int vinc, int v1, int v2){
	D1(cout<<"INIZIO DEBUG calcola_punteggio"<<endl);
	if(vinc == giocatore)
		partita.player1.punteggio=partita.player1.punteggio+PESI[v1%10]+PESI[v2%10];
	if(vinc == computer)
		partita.player2.punteggio=partita.player2.punteggio+PESI[v1%10]+PESI[v2%10];	
	D1(cout<<"FINE DEBUG CALCOLA PUNTEGGIO"<<endl);
}


/** Funzione che gestisce chi ha vinto. Quindi recupera le due carte premute
 *  (saranno quelle con stato selez a true), le confronta tra loro, 
 *  dando la precedenza a quella giocata per prima, poi confrontandole con la 
 *  briscola, e settando il giocatore che ha vinto la mano.
 */
static void gestore_vittoria(){
	D1(cout<<"INIZIO DEBUG gestore_vittoria"<<endl);
	/* Ricordandoci che in passa_turno, abbiamo già cambiato il giocatore, 
	 * quindi alla fine mi ritrovo che adesso gioca è già settato al giocatore
 	 * che ha giocato per primo.
	 */
	
	/* Le variabili val, mi rappresentano il numero della carta(0-39).
	 * val1 --> il num. della carta di chi ha giocato per primo.
	 * val2 --> il num. della carta di chi ha giocato per secondo.
	 */
	int val1, val2;

	// Indici della carta che avrà campo selez a true, ovvero quella giocata.
	int idx_mia_mano;
	int idx_avv_mano;
	
	/* Chiamo ricerca_id_carta per ottenere l'indice della carta premuta:
	 * true per mano giocatore, e false per mano del computer.
	 */
	idx_mia_mano = ricerca_id_carta(true);
	idx_avv_mano = ricerca_id_carta(false);
	D2(cout<<"ripresa carte giocate effettuata con successo"<<endl);
	// Se giocatore ha giocato per primo.
	if(gioca == giocatore){
		val1=partita.player1.mano[idx_mia_mano].val;
		val2=partita.player2.mano[idx_avv_mano].val;
		}

	// Se il computer ha giocato per primo.
	else{
		val1=partita.player2.mano[idx_avv_mano].val;
		val2=partita.player1.mano[idx_mia_mano].val;
		}
	
	/* Adesso di default setto le priorità first alla carta giocata per prima, 
	 * e second a quella giocata per seconda.
	 */
	prior_carta_t priorc1 = first;
	prior_carta_t priorc2 = second;

	// la briscola è l'intero della divisione del mazzo[6].
	//IL +1 È PER NON AVERE UN VALORA 0 DA CONFRONTARE POI CON UN'ALTRO VALORE 0.
	int briscola = (partita.mazzo[6].val/10)+1;
	
	// valuto ora se una delle 2 è briscola, o entrambe
	(val1/10)+1 == briscola ? priorc1=brisc : priorc1=first;
	
	(val2/10)+1 == briscola ? priorc2=brisc : priorc2=second;
	
	//valuto se hanno lo stesso seme
	(val1/10)+1 == (val2/10)+1 ? priorc2=priorc1 : priorc2=priorc2;
	
	// adesso devo gestire il fatto della vittoria
	int vinc;
	
	if(priorc1 == priorc2){
		//deve confrontare la precedenza in base al vettore PREC
		int valor1=PREC[val1%10];
		int valor2=PREC[val2%10];
		
		if(gioca == giocatore && valor1 < valor2)
			vinc=0;

		else if(gioca == computer && valor1 < valor2)
			vinc=1;

		else if(gioca == giocatore && valor1 > valor2){
			gioca=computer;
			vinc=1;
			}

		else if(gioca == computer && valor1 > valor2){
			gioca=giocatore;
			vinc=0;
			}
		}	

	else if(priorc1 < priorc2)
		gioca == giocatore ? vinc=0 : vinc=1;

	else{
		//prima cambia il giocatore, perchè sarà l'altro ad aver vinto
		gioca == giocatore ? gioca=computer : gioca=giocatore;

		//dopodichè, se è giocatore adesso allora vince lui, altrimenti il pc
		gioca == giocatore ? vinc=0 : vinc=1;
		}
	
	calcola_punteggio(vinc, val1, val2);
	D2(cout<<"calcolo del punteggio effettuato con successo"<<endl);
	D1(cout<<"FINE DEBUG GESTORE VITTORIA"<<endl);
}

/** Funzione che pulisce il campo di gioco, facendo scomparire le due immagini
 *  giocate.
 */
void pulisci_tavolo(){
	D1(cout<<"INIZIO DEBUG pulisci_tavolo"<<endl);
	gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,"image2")),
						false);
	gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,"image3")),
						false);
	gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,"image4")),
						false);
	gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object(builder,"image5")),
						false);
	
	// aggiorna la label dei punti, costruendomi sempre una label adatta
	char c[3];
	c[0]=(partita.player1.punteggio/10)+'0';
	c[1]=(partita.player1.punteggio%10)+'0';
	c[2]='\0';
	
	gtk_label_set_label(GTK_LABEL(gtk_builder_get_object(builder,"label1")), c);
	D1(cout<<"FINE DEBUG PULISCI TAVOLO"<<endl);
}


/** Funzione che congela lo stato del gioco quando entrambi i giocatori hanno
 *	 giocato e abilita il mazzo in quanto i giocatori devono pescare prima di
 *  rigiocare.
 */
static void congela_gioco(){
		D1(cout<<"INIZIO DEBUG congela_gioco"<<endl);
		gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(builder,
						"carta1")),false);
		gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(builder,
						"carta2")),false);
		gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(builder,
						"carta3")),false);
		gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(builder,
						"mazzo")),true);
	D1(cout<<"FINE DEBUG CONGELA GIOCO"<<endl);
	}

/** Funzione chiamata ogni volta che la mano termina, ovvero dopo che entrambi
 *  i giocatori hanno giocato una carta.
 *  Quindi la funzione gestisce i punteggi e la vittoria della mano.
 */
static void fine_turno(){
	D1(cout<<"INIZIO DEBUG fine_turno"<<endl);
	/* Congela lo stato del gioco, non è possibile premere
	 * nessun bottone. Abilita il bottone del mazzo
	 */
	congela_gioco();
	D2(cout<<"congelato gioco con successo"<<endl);	
	/* Gestisci chi ha vinto la mano, con tutte le conseguenze, e quindi setta
	 * il turno nel modo appropriato.
	 */
	gestore_vittoria();
	D2(cout<<"gestione vittoria con successo"<<endl);
	/* turno risettato a primo per rigiocare una mano
	 */
	turno = primo;	
	D1(cout<<"FINE DEBUG FINE TURNO"<<endl);
}

/** Funzione che setta la carta che viene messa sul tavolo di gioco.
 *  In base al turno e al giocatore, sceglie una delle 4 posizioni possibili :
 *  -se la carta giocata è del giocatore, allora ha 2 posizioni disponibili,
	  che sono : 1 se ha giocato per primo, la carta andrà sotto, così quella 
	  del computer si sovrapporrà in un pezzo sopra; 2 se ha giocato per secondo
	  la carta  va quindi leggermente sopra a quella giocata dal computer.
 *  -se la carta giocata è del computer, rimane tutto come prima, ma il computer
	  ha anche le due sue posizioni. 
 */
void setta_immagine_tavolo(){
	D1(cout<<"INIZIO DEBUG setta_immagine_tavolo"<<endl);
	int indice;
	if(gioca == giocatore)
		indice=ricerca_id_carta(true);
	else
		indice=ricerca_id_carta(false);
	
	GtkImage *image;
	if(turno == primo){
		if(gioca==giocatore){
			// Prende il rif all'immagine sul tavolo.
			image = GTK_IMAGE(gtk_builder_get_object(builder,"image4"));
			// Setta image con l'immagine giusta del bottone premuto.
			gtk_image_set_from_file(image,partita.player1.mano[indice].nome);
			}
		else{
			image = GTK_IMAGE(gtk_builder_get_object(builder,"image2"));
			gtk_image_set_from_file(image,partita.player2.mano[indice].nome);
			}
		D2(cout<<"immagini settate correttamente quando turno = primo"<<endl);
		}
	else{
		if(gioca==giocatore){
			image = GTK_IMAGE(gtk_builder_get_object(builder,"image3"));
			gtk_image_set_from_file(image,partita.player1.mano[indice].nome);	
			}
		else{
			image = GTK_IMAGE(gtk_builder_get_object(builder,"image5"));
			gtk_image_set_from_file(image,partita.player2.mano[indice].nome);
			}
		D2(cout<<"immagini settate correttamente quando turno = secondo"<<endl);
		}

	// Setta tale immagine a visible.
	gtk_widget_set_visible(GTK_WIDGET(image),true);	
	D1(cout<<"FINE DEBUG SETTA IMMAGINE TAVOLO"<<endl);	
}

/** Funzione che gestisce la fine del turno.
 *  I casi sono due :
 *  1 --> ha giocato solo un giocatore, e deve ancora giocare l'altro.
 *  2 --> hanno giocato entrambi i giocatori, e quindi deve gestire la nuova
	  coppia di turni, conteggio punti, ecc.
 *
 */
void passa_turno(){
	D1(cout<<"INIZIO DEBUG passa_turno"<<endl);
	/* quando il turno è il primo, e il giocatore ha giocato, allora gioca 
	 * automaticamente anche il computer
	 */	
	if(turno == primo){

		if(gioca == giocatore){

			gioca=computer;
			
			turno = secondo;
			
			gioca_mano_pc();
			D2(cout<<"il pc gioca la mano correttamente"<<endl);
			fine_turno();
			D2(cout<<"fine turno gestita correttamente"<<endl);
			}
		// se invece ha giocato il computer, non fare niente	
		D2(cout<<"conclude correttamente passa_turno con turno=primo"<<endl);	
	}

	//quando il turno è il secondo, so già che deve giocare il giocatore
	else{
		gioca=computer;

		fine_turno();
		D2(cout<<"fine turno gestita correttamente"<<endl);
		D2(cout<<"conclude correttamente passa_turno con turno=secondo"<<endl);	
	}
	D1(cout<<"FINE DEBUG SETTA IMMAGINI TAVOLO"<<endl);
}


